package com.kayb.patterns.structural;

import java.util.EnumMap;
import java.util.Map;

/**
 * 享元模式，对象共享池，用于减少对象的创建，通常与单例模式一起使用
 * 场景：各种连接池
 * @author huangkaibin
 * @date 2018-08-28
 **/
public class Flyweight {

    interface Potion {
        void drink();
    }

    static class HealingPotion implements Potion {
        @Override
        public void drink() {
            System.out.printf("You feel healed. (Potion=%s)\n", System.identityHashCode(this));
        }
    }

    static class HolyWaterPotion implements Potion {
        @Override
        public void drink() {
            System.out.printf("You feel blessed. (Potion=%s)\n", System.identityHashCode(this));
        }
    }

    static class InvisibilityPotion implements Potion {
        @Override
        public void drink() {
            System.out.printf("You become invisible. (Potion=%s)\n", System.identityHashCode(this));
        }
    }

    static enum PotionType {
        HEALING, HOLY_WATER, INVISIBILITY
    }

    static class PotionFactory {
        private static final Map<PotionType, Potion> potions = new EnumMap<PotionType, Potion>(PotionType.class);

        public static Potion createPotion(PotionType type) {
            Potion potion = potions.get(type);
            if (potion == null) {
                switch (type) {
                    case HEALING:
                        potion = new HealingPotion();
                        potions.put(type, potion);
                        break;
                    case HOLY_WATER:
                        potion = new HolyWaterPotion();
                        potions.put(type, potion);
                        break;
                    case INVISIBILITY:
                        potion = new InvisibilityPotion();
                        potions.put(type, potion);
                        break;
                    default:
                        break;
                }
            }
            return potion;
        }
    }

    public static void main(String[] args) {
        PotionFactory.createPotion(PotionType.INVISIBILITY).drink(); // You become invisible. (Potion=10568834)
        PotionFactory.createPotion(PotionType.HEALING).drink(); // You feel healed. (Potion=11370630)
        PotionFactory.createPotion(PotionType.INVISIBILITY).drink(); // You become invisible. (Potion=10568834)
        PotionFactory.createPotion(PotionType.HOLY_WATER).drink(); // You feel blessed. (Potion=780376)
        PotionFactory.createPotion(PotionType.HOLY_WATER).drink(); // You feel blessed. (Potion=780376)
        PotionFactory.createPotion(PotionType.HEALING).drink(); // You feel healed. (Potion=11370630)
    }
}
